Repository navigation
feat(spec,metadata-protocol)!: rename the type registry's allowOrgOverride to allowEnvironmentOverlay, on the registry and on GET /meta/types - #22874
Conversation
…rride to allowEnvironmentOverlay The registry flag decides one environment-scope question at every door since ADR-0131 D6 retired the per-organization overlay axis: whether an environment may overlay an item a managed package ships. It is renamed to say so, with the old key a retiredKey() tombstone, a retired-keys entry and a D3 semantic entry (no D2 conversion), and the GET /meta/types wire field moves with it on both writer arms. supportsOverlay's describes and TSDoc are corrected to what it gates: the removal carve-out, no save and no read. WIP: source and spec; tests, docs, tooling and generated artifacts follow. Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
…the rows, the wire and the read-side absence Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
…me allowEnvironmentOverlay; changeset Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
…ected supportsOverlay describes Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
…seal wording (removes no managed definition; changes what is served for permission alone) Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
…positive control Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 11 package(s): 28 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 11 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 149 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 943a21534c96684329ff11ef475c9987036a0073 && git checkout 943a21534c96684329ff11ef475c9987036a0073
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 51b43a8dc45fef9d86229509ab6b2679ffa9d501 49ef13a518dd486eeef521971583f109f098f590 && git checkout -B drift-repro 51b43a8dc45fef9d86229509ab6b2679ffa9d501 && git merge --no-ff 49ef13a518dd486eeef521971583f109f098f590
node scripts/docs-audit/affected-docs.mjs --json 51b43a8dc45fef9d86229509ab6b2679ffa9d501
|
…ture-spec-major) Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
… and the re-recorded lockstep for e531116 - .changeset/console-e5311165a8d6.md: derived by scripts/bump-objectui.sh from the changesets objectui declared over 4997995..e531116 (21 releasing, 4 breaking by annotation), with its ADR-0087 disposition answered: not-required (no-migration-prescription), each declared-breaking objectui change answered in turn. - sdui.manifest.json + scripts/sdui-manifest.record.json: regenerated by scripts/gen-sdui-manifest-node.mjs from the built tree at the pin (107 components; one input description changed). - packages/sdui-parser/objectui-lockstep.json: re-recorded at the pin; the grammar region, the 25 diagnostic codes and the containment predicate are unchanged. Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
…ibe names the pin e531116 Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
This reverts commit e486abb. .objectui-sha is #22874's single-writer path, and objectui from e531116 on reads allowEnvironmentOverlay only, which main's server sends once #22874 lands. The pin move returns as its own PR after #22874. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013XKtmoR5QCUSTMjiQ3os49
Contract reviewServed-tier: PR #22874 (card #22340, stage S2: ① Derived judgments1. The declaration and the tombstone — holds.
2. The wire, both arms — holds; the read-side trap is closed.
3. The kit — holds;
4. The changeset — every sentence true to the diff. 5. The pin — holds.
6. The merge of 7. CI — every check on the head is green or an expected skip. Read through REST at this act: 42 check-runs, 42 completed, 39 ② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
Landing pre-checks at
|
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 38207850018 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
Queue ejection triaged: the suite-duration ceiling step #22949 anchors, not this PR's behaviour. Held, not re-queued
Signature (queue run
Why it is not this diff:
Action: none on the queue. #22949 is the open anchor for this red (p1, While it is held: |
…Overlay`; the read-only banners name `OS_METADATA_WRITABLE` (objectui#12141) (objectstack-ai#12168) Fixes objectstack-ai#12141 Clause-②: yes ## Landing order This pull request merges first. objectstack-ai/objectstack#22340 S2 (PR objectstack-ai/objectstack#22874, held as a draft for the pin round) then bumps `.objectui-sha` to this merge. That is ruling Q1 A / Q2 A (`6073921182`): one landing for the server rename, this companion and the pin, and the order the S2 seat review restates (`6112246741`). - Between the two merges, objectui `main` reads a field the server does not write yet. The bundled console is unaffected, because its pin stays where it is until S2. - There is no dual read of the two names, and no fallback to the old one anywhere in this diff. - Cloud: triage `6109764647` records the pin-pair rule on objectstack-ai/cloud#2709. Cloud's `.objectui-sha` may pass this merge only in the same commit that moves its framework pin to a commit carrying S2. ## What changes **The rename.** `RichMetadataTypeEntry.allowOrgOverride` is now `allowEnvironmentOverlay`, and so is the member `resolveResourceConfig` takes and returns. Both are exported from the package entry, so the published type surface moves; hence `Clause-②: yes` and a `minor` changeset with the breaking semantics stated (this repo's release model, no `major`). Every reader now reads the new name: - the editor's write gates: `canWriteByType` and the designer auto-on effect in `ResourceEditPage`; - the permission matrix's type and artifact tiers in `PermissionMatrixEditor` (only its overlay-flag reads and the comments beside them; the cross-lane declaration is on objectstack-ai/objectstack#15194, `6115259878`); - the type list's create gate (`ResourceListPage`), the embedded item editor's read-only gate, the directory's writable count, its "Writable only" filter and its tile badge (`DirectoryPage`), and the page header badge (`PageShell`'s `WritabilityBadge`); - prose in `BuilderLanding`, `PicklistPreview`, `useMetadata` and `registry`, and `content/docs/guide/console.md`. The renamed member carries a doc comment that names the wire field, its meaning under ADR-0131 D6, and that no other name is read. **The carried banner remedy** (triage `6109764647`). `engine.edit.readOnlyTypeBanner` told an admin to set `OBJECTSTACK_METADATA_WRITABLE` and to "flip {override} in the registry". The server reads only `OS_METADATA_WRITABLE`: objectstack `main` reads it in `envWritableMetadataTypes`, with an empty legacy list. The registry is a TypeScript literal in `@objectstack/spec` that no deployment edits. - The banner now draws `OS_METADATA_WRITABLE` as its code token. It says what the hatch opens: the type's items that no package ships, never an item a package ships. - The `{override}` placeholder and the registry flip are gone, in English and Chinese. - The badge and label tooltips for a hatch-elevated type (`DirectoryPage`'s tile and `PageShell`'s header badge) name `OS_METADATA_WRITABLE` with the same reach. They no longer name the legacy env var. - Why the reach is stated: objectstack `main` applies the hatch to the runtime-only intent only (ADR-0131 D6). Its own refusal sentence names the hatch to say it does not open a managed item. A banner that offered the hatch unqualified on a packaged item would send the operator to a door the server keeps shut. **Same defect class, fixed in place: the permission matrix hints.** This diff edits the two `perm.readOnly*` hints anyway, to rename the key inside them. - `perm.readOnly.artifact.hint` is shown only for a set a code package ships. It offered "ask an operator for the documented OS_METADATA_WRITABLE escape hatch" as a route, and that route does not open such a set (above). It now says the hatch does not open a set a package ships. Cloning, redeploying the source and a new runtime set are unchanged. - `perm.readOnly.hint` (a type with no runtime write channel) keeps the hatch as a remedy and states its reach. - The two tests that pinned the hatch as a route now pin the new sentence instead (`PermissionMatrixEditor.artifactTier` and `PermissionMatrixEditor.cloneToCustomize`). The second also asserts that the old route wording is absent. - The bounded in-place conditions all hold: the defect class is this card's; the shape is pinned by the server's own sentence; both files are in the claim's surface; and no new verification surface is added. **Not changed, as this seat ruled:** the artifact-tier gate's logic. It still reads the flag alone; see the finding below. ## Premise checks (measured on `d2500d8`) - H1: the readers were 11 non-test files (10 under `views/metadata-admin/` plus `studio-design/BuilderLanding.tsx`), 49 hits. The field was also named in 59 test files (114 hits). `StudioHomePage.tsx` is gone. The rename touched exactly 71 files: those, plus the docs page. - H2: the export was confirmed on the built closure. `dist/index.d.ts` re-exports `RichMetadataTypeEntry` and `resolveResourceConfig`. After the build, `useMetadata.d.ts` and `registry.d.ts` carry `allowEnvironmentOverlay` and no `allowOrgOverride`. - H3: confirmed. The strings live in the designer table (`views/metadata-admin/i18n.ts`, en and zh) and in the two tooltips. `packages/i18n` has none of them. - H4: confirmed. Nothing reads the old name. ## Verification (final head `2c38817`) - Dependency closure: `turbo run build --filter='@object-ui/app-shell^...' --concurrency=2`, 28 of 28 tasks successful. `pnpm --filter @object-ui/app-shell build` passed, with dist completeness 1062 files verified. - `pnpm --filter @object-ui/app-shell type-check` (it echoes `tsc --noEmit && tsc -p tsconfig.test.json`; the second project includes every `src/**/*.test.tsx`): exit 0. - Targeted vitest over every test file this diff touches or adds, 61 files: 20 files with 120 tests passed, and 41 files with 212 tests passed. The two new files and four of the edited ones were re-run on `2c38817`: 6 files, 70 tests passed. - New pins: - `ResourceEditPage.environmentOverlay-12141`: for each of `view`, `dashboard`, `report`, `translation` and `email_template`, a packaged item is editable when served the field (both flags true, as S2's registry declares them), and the same item without the field stays locked. Negative control: `api`, without overlay or runtime create, stays read-only. Its banner names `OS_METADATA_WRITABLE` and no registry flip, in en and zh. - `DirectoryPage.environmentOverlay-12141`: the tiles and the header badge for the five types; a hatch-elevated `agent`, whose only open door is the overlay flag, is badged writable and counted; `api` and the field-less `agent` are read-only and not counted. - Ablation: four mutations through `ablation-replace` (literal anchors, the landing checked on disk, a trap that restores, and a restore proven by HEAD blob hash with `git diff HEAD` empty): - the artifact arm of `canWriteByType` reading the old name: 5 failed of 12, the five positive cases; - `WritabilityBadge` reading the old name: 6 failed of 10; - the directory's writable count reading the old name: 1 failed of 10; - the banner token printing the legacy env var: 2 failed of 12, en and zh. All four turned red in the expected direction, and each restore was blob-equal. - Gates, all exit 0 at `2c38817`: `check-changeset-presence`, `check-changeset-no-major`, `check:changeset-claims`, `check:pending-changeset-literals`, `check:control-bytes`, `check:new-line-citations` (0 new), `check:phantom-deps`, `check:i18n-keys`, `check:i18n-drift` (3 designer en values changed, 3 zh followed), `check:i18n-designer-parity`, `docs:check-links`, `check:doc-fences`, `check:test-path-roots`, and `check:vi-mock-specifiers` / `-inherit` / `-override-shape`. - Lint, narrowed to the 72 changed TypeScript files and run as the package's own `eslint .` runs (no type-aware linting is configured, and no custom rule reads another file, so the verdict on an untouched file cannot move): 72 files, 0 errors, 176 warnings. All of the warnings were already there, and the two new test files have none. - NOT MEASURED: `check:eager-closure`, because it needs the full console build, which CI's performance-budget job owns. The diff adds 328 net bytes, uncompressed, of shipped strings to the designer table (en and zh together). ## Acceptance notes (observed; not filed) - **The hatch value is wider than what it opens** (out of scope by this seat's ruling). - A probe render, not committed, used an `agent` entry the hatch elevates (`allowEnvironmentOverlay: true`, `overrideSource: 'env'`, no runtime create) and a packaged item. The editor offers Edit. - objectstack `main` refuses that save: the hatch admits the runtime-only intent only, and ADR-0131 D6 seals managed content. That is read from the server source, not measured live. - The S2 describe of the field says the elevation never opens a managed item. - Whether the artifact tier should also read `overrideSource` is this lane's call. It is reported to the seat. - The landing UI copy (`engine.studio.landing.*`) and some comments still say "org overlay" after ADR-0131 D6 retired the per-org axis. That is wording only. - `PermissionMatrixEditor`'s type-gate comment carries three stale cross-file line addresses. They were left alone because this diff touches only that file's overlay-flag reads, as the cross-lane declaration states. - `PermissionMatrixEditor.cloneToCustomize`'s refused-save fixture quotes a pre-D6 server sentence (an escape-hatch remedy the server no longer prints). It is a fixture of the client showing the server's words, so it was left as is. --- _Generated by [Claude Code](https://claude.ai/code/session_016djJF12Qt14ejKR5Vjt4sK)_ --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: objectstack-fleet[bot] <332303061+objectstack-fleet[bot]@users.noreply.github.com>
…etired category and isSystem keys (objectstack-ai#12193) Part of objectstack-ai/objectstack#22876 The objectui half of the `email_template.category` / `email_template.isSystem` retirement (ADR-0049 enforce-or-remove). This PR leaves that card open: the spec half is the objectstack PR on branch `claude/issue-22876-dead-key-retirement-batch`, which lands after this one and after a `.objectui-sha` bump past this merge. ## What changed One file, `packages/app-shell/src/views/metadata-admin/default-schemas.ts`, plus a `patch` changeset for `@object-ui/app-shell`: - **`email_template` entry:** the `category` enum input and the `isSystem` checkbox are removed. `@objectstack/spec` retires both keys with `retiredKey()` tombstones, so a form that still offered them could write a key the server refuses. A comment in place says why. - **Same-file rider, same class (declared in the claim):** the `skill` entry's `triggerPhrases` input is removed. The spec retired that key in 17 and its parse already refuses it. - **The file header is corrected.** It said the fallback schemas are used "for every type today", because the framework did not serve schemas. The framework now derives a `schema` for each type on `/meta/types` (with a hand-crafted fallback for a type that does not derive), and `ResourceEditPage` reads `entry.schema` first and `defaultSchema` second. The header now says the fallback is read only when the server serves no schema for the type, and that an entry must not offer a retired key. Nothing is added to or removed from the package entry. ## Why this is hygiene, not a save fix (measured) - Against a current server, Studio renders the served schema and the served `email-template.form.ts`, not this file. Booted on the objectstack branch (showcase, `--fresh`): `GET /api/v1/meta/types` serves the `email_template` schema without `category` or `isSystem`, and its form fields are `name`, `label`, `locale`, `description`, `subject`, `bodyHtml`, `bodyText`, `variables`, `fromOverride`, `replyTo`, `active`. - Removing the two fields is harmless against v17 and v18 servers: both keys are optional there, and `category` has a default. ## Evidence (head `5f409db9`) - `pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/metadata-admin/` from the repo root: 476 files passed, 5401 tests passed, 1 skipped, exit 0. Scope: every importer of `default-schemas.ts` lives in `metadata-admin/` (`index.ts`, `register-builtins.ts` and three tests). Run under the shared verify lock on a shared box. - `pnpm exec turbo run type-check --concurrency=2 --filter=@object-ui/app-shell`: 30 of 30 tasks passed, including `app-shell:type-check` (`tsc --noEmit && tsc -p tsconfig.test.json`), exit 0. - `node scripts/check-changeset-presence.mjs`: exit 0. It found 1 changed source file of 1 released package, declared by 1 changeset. - `node scripts/check-changeset-no-major.mjs`: exit 0. - `node scripts/check-new-cross-file-line-citations.mjs`: 0 new citations, exit 0. - `pnpm exec eslint` on the changed file: exit 0. ## Landing order (triage ruling on the card, kept) 1. This PR: safe to land at any time. 2. A separate `.objectui-sha` bump card in objectstack, to a commit at or past this merge. It queues behind objectstack-ai/objectstack#22874, which holds that path today. 3. The objectstack retirement PR, parked in draft until the pin carries this change. --- _Generated by [Claude Code](https://claude.ai/code/session_019G5ZnRrTMiwcHG6iZM19zf)_ Co-authored-by: Claude <noreply@anthropic.com>
Part of #22340
Clause-②: yes (narrowing)
ADR-0131 C5's spec half (stage S2): the metadata type registry's
allowOrgOverrideis renamed toallowEnvironmentOverlay, onDEFAULT_METADATA_TYPE_REGISTRYand on theGET /meta/typeswire field, under ruling C on #22007 (6028809298), ruling6073921182(Q1 A, Q2 A) and the pre-build contract review6109457426, which fixed the name. #22340 stays open for S3, the governed text.The console pin moves with the rename, in this PR.
.objectui-shais objectuie5311165a8d6, the merge of objectstack-ai/objectui#12168, which carries objectstack-ai/objectui#12141: from that commit on, objectui's metadata admin reads the wire field under its new name only, with no dual read. The two halves land together. Any other pin bump paste5311165a8before this PR lands would show the five overlay-enabled types read-only in Studio. The landing record is the contract review on this post-pin head.What changes
MetadataTypeRegistryEntry.allowEnvironmentOverlay(defaultfalse) with the contract review's describe and TSDoc.allowOrgOverrideis aretiredKey()tombstone onMetadataTypeRegistryEntryBaseSchemawhose prescription names the new key: the old key failstscand fails the parse (invalid_typeatallowOrgOverride). The prescription reads "was renamed toallowEnvironmentOverlay(ADR-0131 D6)" and names no version: the changeset ships this asmajoron the18.0.0-nextline, and the TSDoc's "in 18" names the protocol major. All 28 built-in rows spell the new key; every value is unchanged (the true set isview,dashboard,report,translation,email_template).18.kernel__MetadataTypeRegistryEntry__allowOrgOverride; D3 semantic entrymetadata-type-registry-allow-org-override-renamed, covering the registry key AND the wire field; itsSTEP18_RATIONALEfragment (order 94). No D2 conversion, as ruled: no manifest, stack or stored row can carry a registry entry. Noregistry.ts,spec-changes.jsonor upgrade guide is committed (git-ignored, generated).getMetaTypeswrites theOS_METADATA_WRITABLEelevation ontoallowEnvironmentOverlayon BOTH arms: the registry arm (the...basespread already carries the new key, and the elevated value overwrites it) and the synthesised arm of a runtime type with no registry row. No entry carriesallowOrgOverride. The field's describe says the elevation opens only items no managed package ships;overrideSourcekeepsregistry/envand its describe names the new field.undefined, which closes all five types. The readers moved by hand:protocol.tsgetMetaTypes(both arms) andOVERLAY_ALLOWED_TYPES, andsys-metadata-repository.ts'sOVERLAY_ALLOWED_TYPES. Every test reader moved with them.supportsOverlaykeeps its name and both keys stay (contract review item 2: ADR-0049 retires neither). Its TSDoc and its three describes (registry,GetMetaTypesResponse,MetadataTypeInfoResponse) and the stale read claims inprotocol.tsandsys-metadata-repository.tsnow say what it gates: the delete carve-out, no save and no read. Wording used: PR fix(metadata-protocol): S5 carry-overs — per-term boot report isolation, one naming of a code-datasource row, seal TSDoc wordings, two changeset rows #22833's, which landed (8c105e3d67) before this branch mergedmain: the removal "removes no managed definition, and changes what is served forpermissionalone".email-template.zod.ts,kernel/index.ts, thecustomizationPoliciesprescription (and its pin), the unreleased D3metadata-customization-protocol-retiredand its fragment, and the comments inprotocol.ts,rest-server.ts, runtimepackages.ts/mcp.tsandsys-flow-credential.object.ts. A comment that records history keeps the name of its time:sys-metadata-repository.tsstill says commitee58392e1rolledallowOrgOverrideback.allowEnvironmentOverlay"; theirORG_OVERRIDABLEidentifiers are nowPRE_D6_ORG_SCOPED. The two plugin-security doubles throw the sentence the producer emits today.metadata-lifecycle.mdx's whitelist table header moves withcheck-overlay-whitelist-table.mjs'sCOL_FLAGand its self-test fixtures, in one change; 10 morecontent/docspages; 8 platform-checklist files, bothmetadata-plugin.zod.ts#allowOrgOverrideanchors re-pointed to#allowEnvironmentOverlay(revision-historychangeentries keep the old name); 3 liveness notes; 2 ADR anchors; the regenerated references.majoron the v18 pre-mode line, the22572precedent): BREAKING, the FROM / TO table for registry entries and/meta/typesentries,Clause-②: yes (narrowing)and the ADR-0087registeredmarker.The console pin (round 2)
The hop. objectui
4997995022f8..e5311165a8d6(.objectui-shawas4997995022f8onmainat the merge): 24 commits, all non-merge squashes, over 287 paths (214 modified, 69 added, 4 deleted, none renamed), +13412 / −2428. objectui4baa8a67c4(objectui#12170:slotsForTypestops reading the retiredflow-templateledger role) is INSIDE it, two commits below the new tip:git merge-base --is-ancestor 4baa8a67c4 e5311165a8exits 0, and--is-ancestor 4baa8a67c4 4997995022f8exits 1, read in a full (non-shallow) clone whose control leg (d32869883b, 50 commits below the old pin) answers 0. Its changeset is release-nothing, so the console changeset counts it among the 2 release-nothing changesets rather than listing it.The Console Pin Gate's steps, run locally on this head:
turbo run build --filter=@objectstack/client...exit 0;scripts/build-console.shexit 0 ate5311165a8d6(objectui cloned from the pin into.cache/, 8872 modules; bundle canaryimport/jobspresent; one zod version literal; "Console bundle carries THIS tree's @objectstack/spec, and only it"); the dist and its.objectui-shastamp in place;pnpm check:console-shaexit 0 (objectui@e5311165a8d6);pnpm check:console-injection --require-stampexit 0. The injection's stale detector is the published spec's describe of the retired key, "Allow per-org overlay writes via runtime metadata API", and it is absent from the bundle.Against this PR's wire. The built bundle's app code reads
allowEnvironmentOverlay15 times (metadata-admin,packagedActionsand the shell; for example the read-only verdict is!u.allowEnvironmentOverlay && !u.allowRuntimeCreate).allowOrgOverrideoccurs only inside this tree's spec, in the tombstone and its prescription text (4 occurrences, all in thevendor-objectstackchunk); no app code reads it. Then the two together, on a booted backend:pnpm dev -- --fresh -p 38977on this head (showcase, the console dist above,check:console-shagreen at boot). The liveGET /api/v1/meta/typesanswered 34 entries: all 34 carryallowEnvironmentOverlay, none carriesallowOrgOverride, andtrueis exactlyview,dashboard,report,translationandemail_template, each withoverrideSource: registry. In a headless Chromium signed in as the seeded admin, the console's Setup metadata pages read that wire: a packagedview(showcase_task.in_progress) and a packageddashboard(showcase_chart_gallery) open with thewritablebadge and an editable designer, while a packagedflow(showcase_task_completed) and a packagedobject(showcase_account) opencreate-onlyand "locked". No page namesallowOrgOverride. The server was stopped afterwards. In process, thegetMetaTypespin (protocol-meta-types-rich.test.ts) and S1's five-type file on both topologies are green on this head.The artefacts that travel with the pin, in the shape PR #22794 used:
.changeset/console-e5311165a8d6.md, derived byscripts/bump-objectui.shfrom the changesets objectui declared over the range (21 releasing, 4 breaking by their authors' annotation, no declaredmajor). Its ADR-0087 disposition isnot-required (no-migration-prescription), and it answers each declared-breaking objectui change: objectui#12141 is this PR's own rename, whose prescription andregistereddisposition live in22340-registry-allow-environment-overlay.md; the three objectui#12130 changes move objectui's own form-field face, no ObjectStack key.sdui.manifest.jsonandscripts/sdui-manifest.record.json, regenerated from the built tree at the pin: 107 components; one input description changed (the record activity feed'sshowCompleted, objectui#12106), and no component, input, type or required flag moved.packages/sdui-parser/objectui-lockstep.json, re-recorded at the pin: the 214-line grammar region, the 25 diagnostic codes and the containment predicate are unchanged..changeset/objectui-pin-citations-e5311165a8d6.md(@objectstack/specpatch,Clause-②: no) and the re-measured citations. All 55 asserting citations (49 hand-written, 6 in the generated migrations registry) were mapped through the hop. Five cited files changed (ObjectGrid.tsx,data-table.tsx,form.tsx,record-related-list.tsx,data-objectstack/src/index.ts) and every cited line in them moved or held byte-identical; each record gains a hop sentence, and the anchors that moved are re-pointed where the records cite them at this pin. The six migration entries' corpus counts were re-taken withgit grep -o -F(8506 tracked files; 124 zero tokens still zero;Span517 to 519, both new hitscolSpan).check:objectui-pin-citations --verify-anchorsagainst objectui at the pin: 55 asserting citations match, 13 anchor content assertions verified.New pins
kernel/metadata-type-registry-allow-org-override-retirement.test.ts: the parse refuses the old key with the rename (code, path, prescription text;falserefused liketrue); the new key parses and defaults tofalsewith no old key grown back; every built-in row states the new key, none the old, and the true set is exactly the five; the retired-keys registration.kernel/metadata-type-registry-allow-org-override-absence.test.ts(repoproject, radius already declared for@objectstack/spec#test:repo): a tree-scoped, AST-read absence of any CODE reference toallowOrgOverrideinpackages/**/*.tsandexamples/*/src/**/*.ts. Comments and strings are history and are not judged; the tombstone declaration is exempt by shape. The sibling refusal pin is counted apart and REQUIRED to be found, so the walk carries a live positive control.objectql/protocol-meta-types-rich.test.ts: both writer arms carryallowEnvironmentOverlay, the hatch elevation lands on it on both arms, andnot.toHaveProperty('allowOrgOverride')on every entry.environment-overlay-five-types.test.tsunder the new name on both topologies, plus the wire absence; the identity pins (org-scoped-write-refused,adr0005-org-override-rollback,overlay-precedence) read the new key.Ablation (round 1; committed fix first; restored blob-equal)
Dropped the hand rename of
OVERLAY_ALLOWED_TYPES's reader (if (!entry.allowEnvironmentOverlay) continue;back to the old key) throughscripts/ablation-replace.mjs: anchor 1 → 0, mutant 0 → 1 on disk;@objectstack/metadata-protocolrebuilt;ablation-dist-preflightfound the marker indist/index.jsanddist/index.cjs. S1's five-type file: 20 failed / 6 passed of 26 (the 6 are the wire and identity cases, which do not read that set). Restored: blobeff1a12c83e2equals HEAD,git diff HEADempty; rebuilt; preflight--absentclean over 24 built files; the same file 26 / 26 passed.Readings (head
49ef13a518)allowOrgOverridein non-test source: the tombstone, its prescription and TSDoc, the registry's naming note, the retired-keys and D3 entries, the rationale fragment, two shipped protocol-17 D3 entries,18.metadata-write-organization-scope-refused(history), the generatedauthorable-surface/kernel.json[RETIRED]row and the untouchedauthorable-surface.base.json, four history comments (protocol.tsretired exemption, a quoted docs sentence and the commitee58392e1record insys-metadata-repository.ts,rest-server.ts), two ADR-anchor history notes, and the checker's header note. No code reference (the absence pin).authorable-surface/kernel.json,authorable-defaults/kernel.json, four reference pages), pin tests (radius declared), examples (one comment), docs, changeset, thecheck:generatedsource audits and the dogfood radius. Do not apply: orphan value schema (boolean), D2 conversion (ruled out), liveness ledger row (none exists for the registry entry; the three prose notes follow the name), forms and i18n (no*.form.tsinput), CLI advisory lint (ledger-driven, no row), published skills (S3).api-surface,json-schema.manifestandexport-originsdo not move (no export renamed);authorable-surface.base.jsonis written only bygen:authorable-surface-baseand is untouched.acceptRetiredDefaultResidueis not needed: no built artifact or stored row carries a registry entry.Not in this PR
AGENTS.mdPrime Directive 7,skills/objectstack-ai/SKILL.md, ADR-0005 (and the dated ADR records).service-ai-studiowrite-door.tsandmetadata-tools.test.ts): recorded on the card (6109343061item 5) for a seat that reaches cloud.Acceptance notes
check:platform-checklistis red on this head on 8 findings in files this PR does not touch, each byte-identical tomain: the 7 recorded in round 1 (areas/access-security.json,areas/attachments-storage.json) and one more,areas/search.jsoncitingprotocol.ts#countable, a symbol main's PR fix(objectql,metadata-protocol,spec): a paged search reports the counted total #22857 (55382dc02a) removed.countablereads 0 inprotocol.tsonorigin/mainand on this head. Not this diff.pnpm --filter @objectstack/spec check:migration-registrydoes not exist (the registry is git-ignored and generated);gen:migration-registryran green on this head (424 semantic, 259 retired-key, 222 retired-def).mainat018b077fbf(round 2, throughos-regen-merge.sh; two hand-written conflicts,email-template.zod.tsandliveness/README.md, resolved by stacking both intents).mainhas moved 9 commits since;git merge-tree --write-tree HEAD origin/mainis clean, and none of those commits adds a line naming either key or an asserting pin citation.Verification (head
49ef13a518)@objectstack/spec:typecheckexit 0;test(local) 649 files / 19398 tests passed (1 todo);repoproject: the absence pin,retired-key-migrate-sentenceandstep18-rationale-merge, 3 files / 26 tests passed.@objectstack/metadata-protocol:test226 files passed, 3 skipped (28171 tests passed, 19 skipped);typecheckexit 0.@objectstack/objectql: S1'senvironment-overlay-five-types.test.tsand the wire pinprotocol-meta-types-rich.test.ts, 2 files / 33 tests passed.turbo run build --filter=@objectstack/example-showcase...(61 tasks, exit 0); later, eight packages outside that closure, by name, for two gates' prerequisites and the boot (client-react, the five packagescheck:published-readme-exportsreads,studio,service-cluster-redis). Nopnpm build.check:generatedexit 0 (all 14 artifacts up to date against that dist);check:api-surface"unchanged";check:authorable-surfaceexit 0 (authorable-surface.base.jsontrails018b077fbf88, an information line);check:future-spec-majorexit 0 (no citation names a major above 17, with the version word gone from the prescription).node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no paths) at this head printed 155 commands; every one run except two, and--ranreconciles: 155 derived, 153 run, 2 NOT-MEASURED (claimed), 0 UNRUN. Exit codes: 152 × 0 andcheck:platform-checklist× 1 (above).check:skill-examplesfirst refused with exit 3 (@objectstack/client-reactunbuilt), then exit 0 after that package was built. NOT MEASURED:check:dual-build-cjs-loads(no whole-workspace build this round) andcheck:type-check-debt(the derived command is the--re-measurethis round does not run).PR_NUMBER=22874,PR_HEAD_REF,PR_BODYandGITHUB_REPOSITORYwired forclosing-target-claim,partof-closing-keywordandsingle-claim-paths: 41 × exit 0. Two needed a rerun:check:published-readme-exportsrefused with exit 3 until five packages outside the showcase closure were built, andcheck:select-shard-packages's self-test compared output that the proxy variable the PR-context guards need had polluted with a warning; rerun without it, exit 0.check:pm-dispatch-gates(fast tier): 1828 cases pass, exit 0.check-adr-0087-registration --base origin/mainexit 0: two declared-breaking changesets,22340-registry-allow-environment-overlay.md(registered metadata-type-registry-allow-org-override-renamed) andconsole-e5311165a8d6.md(not-required (no-migration-prescription)).Round 2 (the pin round) was written by session
session_01KNKBCRDJCu5tGy3TEbvtrFunder claim6109485204, on the seat's order6117020961.